#!/bin/bash
#
# Copyright(c) 2012-2021 Intel Corporation
# SPDX-License-Identifier: BSD-3-Clause
#

. $(dirname $3)/conf_framework

check() {
	cur_name=$(basename $2)
	config_file_path=$1
    if compile_module $cur_name "bio_split(NULL, 0, 0, 0);" "linux/bio.h"
    then
        echo $cur_name "1" >> $config_file_path
    elif compile_module $cur_name "bio_split(NULL, 0);" "linux/bio.h"
    then
        echo $cur_name "2" >> $config_file_path
    else
        echo $cur_name "X" >> $config_file_path
    fi
}

apply() {
    case "$1" in
    "1")
        add_function "
    static inline struct bio *cas_bio_split(struct bio *bio, int sectors)
    {
        return bio_split(bio, sectors, GFP_NOIO, NULL);
    }" ;;
    "2")
        add_function "
    static inline struct bio *cas_bio_split(struct bio *bio, int sectors)
    {
        struct bio *split, copy;
        int bytes = sectors << 9;
        uint32_t idx, vecs = 0;
        int ret;

        copy = *bio;
        copy.bi_io_vec = &copy.bi_io_vec[copy.bi_idx];
        copy.bi_vcnt -= copy.bi_idx;
        copy.bi_idx = 0;

        BUG_ON(bytes >= bio->bi_size);

        // For simplicity we assume that split is alligned.
        // Otherwise bvec modification would be required.
        while (bytes) {
            if (bytes >= bio_iovec_idx(&copy, vecs)->bv_len) {
                bytes -= bio_iovec_idx(&copy, vecs)->bv_len;
                vecs++;
            } else {
                vecs++;
                break;
            }
        }

        split = bio_alloc_bioset(GFP_NOIO, vecs, NULL);
        if (!split)
            return NULL;

        copy.bi_max_vecs = vecs;
        __bio_clone(split, &copy);
        split->bi_size = sectors << 9;
        split->bi_vcnt = vecs;

        if (bio_integrity((&copy))) {
            ret = bio_integrity_clone(split, bio, GFP_NOIO);
            if (ret < 0) {
                bio_put(split);
                return NULL;
            }
            for (idx = 0, bytes = 0; idx < bio->bi_idx; idx++)
                bytes += bio_iovec_idx(bio, idx)->bv_len;
            bio_integrity_trim(split, bytes >> 9, sectors);
        }

        bio_advance(bio, split->bi_size);

        return split;
    }" ;;
    *)
        exit 1
    esac
}

conf_run $@
